<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;

use App\Models\Turn;
use App\Models\Wallet;
use App\Models\Message;
use App\Models\Property;
use App\Models\PropertyInfo;

use App\Library\BTC\BitcoinFunction;
use App\Library\ETH\EthereumFunction;
use App\Library\OBA\ObaFunction;

use Exception;
use DB;

/**
 * 执行转出操作
 */
class HandleTurnOut extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'handle:turn_out';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = '执行转出操作';

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        //获取转出记录为等待区块确认的所有记录
        $turns = Turn::where(['type' => 2, 'status' => 4])->get();
        echo collect($turns)->count();
        if (collect($turns)->count() > 0) {
            foreach($turns as $turn) {
                //选择执行转出的系统钱包
                $wallet = Wallet::find($turn->wallet_id);
                try {
                    //查询用户锁定资产
                    $balance = $turn->user->currency_property($turn->cid)->first()->blocked ?? 0;
                    //锁定资产小于提现额度
                    if ($balance < $turn->real_num) {
                        //抛出错误
                        throw new Exception('用户余额不足提现！');
                    }
                    //判断是否支持币种
                    if (!in_array($turn->currency->name_en, ['ETH','BTC','LTC','DGC','OBA'])) {
                        //抛出错误
                        throw new Exception('暂不支持该币种自动转出！');
                    }
                    //开启事务
                    DB::beginTransaction();
                    //OBA
                    if ($turn->currency->name_en == 'OBA') {
                        //OBA处理类
                        $oba = new ObaFunction();
                        //验证用户钱包地址是否有效
                        $valid = $oba->addressValidator($turn->wallet_address);
                        //地址验证失败
                        if (!$valid) {
                            //抛出错误
                            throw new Exception('地址不合法');
                        }
                        //钱包当前余额
                        $balance = $oba->getBalanceByAddress($wallet->address);
                        //余额小于等于实际提现数量
                        if ($balance <= $turn->real_num) {
                            //抛出错误
                            throw new Exception('系统钱包当前余额不足！');
                        }
                        //发币地址
                        $fromAccount = $wallet->address;
                        //私钥
                        $privateKey = $wallet->private_key;
                        //用户账号
                        $toAccount = $turn->wallet_address;
                        //发起交易
                        $res = $oba->makeTransaction($turn->real_num, $fromAccount, $toAccount, $privateKey);
                        //交易错误
                        if ($res['status'] == 0) {
                            //抛出错误
                            throw new Exception($res['msg']);
                        }
                    }
                    //以太币
                    if ($turn->currency->name_en == 'ETH') {
                        //以太坊处理类
                        $ethereum = new EthereumFunction();
                        //验证用户钱包地址是否有效
                        $valid = $ethereum->addressValidator($turn->wallet_address);
                        //验证失败
                        if (!$valid) {
                            //抛出错误
                            throw new Exception('地址不合法');
                        }
                        //钱包当前余额
                        $balance = $ethereum->getBalanceByAddress($wallet->address);
                        //余额小于等于提现实际数量
                        if ($balance <= $turn->real_num) {
                            //抛出错误
                            throw new Exception('系统钱包当前余额不足！');
                        }
                        //发币地址
                        $fromAccount = $wallet->address;
                        //用户账号
                        $toAccount = $turn->wallet_address;
                        //转为wei单位
                        $wei = $ethereum->toWei($turn->real_num);
                        //转16进制
                        $value = $ethereum->toHex($wei);
                        //发起交易 (待跟踪)
                        $res = $ethereum->makeTransaction($fromAccount, $toAccount, $value);
                        //发生错误
                        if (isset($res['status']) && $res['status'] == 0) {
                            //抛出错误
                            throw new Exception('发起交易失败');
                        }
                    }
                    //比特币，莱特币，狗币
                    if (in_array($turn->currency->name_en, ['BTC','LTC','DGC'])) {
                        //比特币处理类
                        $btc = new BitcoinFunction($turn->currency->name_en);
                        //验证用户钱包地址
                        $check = $btc->addressValidator($turn->wallet_address);
                        //验证失败
                        if (!$check) {
                            //抛出错误
                            throw new Exception('地址不合法');
                        }
                        //当前余额
                        $balance = $btc->getBalanceByAddress($wallet->address);
                        //余额小于等于提现实际数
                        if ($balance <= $turn->real_num) {
                            //抛出错误
                            throw new Exception('系统钱包当前余额不足！');
                        }
                        //发币地址
                        $fromAddresses = $wallet->address;
                        //发起交易（待完善）
                        $res = $btc->makeTransaction($turn->real_num, $fromAddresses, $turn->wallet_address);
                        //dd($res);
                    }
                    //用户资产
                    $property = Property::where(['uid' => $turn->uid, 'cid' => $turn->cid])->first();
                    //减少余额
                    $property->decrement('blocked', $turn->num);
                    //减少总资产
                    $property->decrement('total', $turn->num);
                    //写入资产详情
                    PropertyInfo::create([
                        'uid' => $turn->uid,
                        'cid' => $turn->cid,
                        'oid' => $turn->id,
                        'note' => '提币',
                        'num' => $turn->real_num,
                        'price' => 0,
                        'total' => 0,
                        'proc' => $turn->proc,
                        'type' => 8,
                        'deal_type' => 1,
                        'status' => 1
                    ]);
                    //修改turn表状态
                    $turn->update(['status' => 2]);

                    //解锁钱包
                    $wallet->update(['status' => 0]);

                    //写入消息
                    $msgArr = [
                        'msg_id' => 14,
                        'uid' => $turn->uid,
                        'message' => [$turn->currency->name_en,$turn->wallet_address,$turn->num],
                        'push_message' => [$turn->currency->name_en],
                    ];
                    //dump($msgArr);
                    (new Message())->syspublishsmsAll($msgArr);

                    //提交事务
                    DB::commit();

                } catch (Exception $e) {
                    //回滚事务
                    DB::rollback();
                    //接收错误提示
                    $msg = $e->getMessage();

                    echo $msg;
                }
            }
        }
    }
}
